package com.LensBlaster;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;

/**
 * Homescreen is the first interface presented to the user. It allows users to 
 * view all photos, navigate to a preferences pane, view individual albums,
 * and create new albums.
 * 
 * @author Jake
 */
public class Homescreen extends ListActivity {
	private static final int ACTIVITY_CREATE_ALBUM=0;
	private static final int ACTIVITY_ALBUM_VIEW=1;
	
	private static final int ALBUM_CREATE_ID = Menu.FIRST;
	
	private final static int ALL_PHOTOS_ALBUM_LIST_ITEM_ID = 1;
	private final static int PREFERENCES_LIST_ITEM_ID = 2;
	
	private final static String ITEM_TITLE = "title";
	private final static String ITEM_CAPTION = "caption";
	private final static String ITEM_ICON = "icon";
	
	private LensBlasterDB mDbHelper;
	private Cursor mAlbumsCursor;
	private SeparatedListAdapter mSeparatedList;
	
	/**
	 * Called when the activity is first created.
	 * No preconditions.
	 */
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);

		mDbHelper = new LensBlasterDB(this);
		mDbHelper.open();
		//Hide title bar, we're using our own headers
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		
		fillData();
	}

	/**
	 * Refreshes the Homescreen
	 */
	private void fillData() {
		mSeparatedList = new SeparatedListAdapter(this);
		
		/** create fixed list at top **/
		//Generate photo count for "All Photos" list item description
		final int photoCount;
		mAlbumsCursor = mDbHelper.fetchAllPhotos();
		if (mAlbumsCursor!=null){
			photoCount = mAlbumsCursor.getCount();
			mAlbumsCursor.close();
		} else {
			photoCount = 0;
		}
		
		List<Map<String,?>> fixedList = new LinkedList<Map<String,?>>();
		fixedList.add(createItem("All Photos", photoCount + ( photoCount==1 ? " Photo" : " Photos"), R.drawable.events_icon ));
		fixedList.add(createItem("Settings", "Accounts, etc.", R.drawable.prefs_icon ));
		
		mSeparatedList.addSection(
				"LensBlaster", 
				new SimpleAdapter(
					this,
					fixedList,
					R.layout.list_complex,
					new String[] { ITEM_TITLE, ITEM_CAPTION, ITEM_ICON },
					new int[] { R.id.list_complex_title, R.id.list_complex_caption, R.id.list_complex_icon }
				)
			);
		
		/** create albums list **/
		// Get all of the rows from the database and create the item list
		mAlbumsCursor = mDbHelper.fetchAllAlbums();
		startManagingCursor(mAlbumsCursor);
		
		//Create an array to specify the fields we want to display in the list (only TITLE)
		String[] from = new String[] { LensBlasterDB.ALBUM_KEY_TITLE };
		
		// and an array of the fields we want to bind those fields to (in this case just text1)
		int[] to = new int[] { R.id.list_item_title };
		
		// Now create a simple cursor adapter and set it to display
		SimpleCursorAdapter albums = 
				new SimpleCursorAdapter(this, R.layout.list_item, mAlbumsCursor, from, to);
		
		mSeparatedList.addSection("Albums", albums);
		
		//output list
		setListAdapter(mSeparatedList);
	}

	/**
	 * Utility class for constructing complex SeparatedListAdapter items
	 * @param title Title of the separated list item.
	 * @param caption Short description of the separated list item.
	 * @param icon Associated image resource.
	 * @return a mapping of complex SeparatedListAdapter item types and their associated values
	 */
	private Map<String,?> createItem(String title, String caption, int icon ) {
		Map<String,Object> item = new HashMap<String,Object>();
		item.put(ITEM_TITLE, title);
		item.put(ITEM_CAPTION, caption);
		item.put(ITEM_ICON, icon);
		return item;
	}
	
	/**
	 * We construct the menu options here.
	 * @param menu The menu to which we add menu items.
	 * @return True to display the menu; false to keep it hidden.
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, ALBUM_CREATE_ID, 0, R.string.menu_album_create);

		return true;
	}
	
	/**
	 * Handles menu item selection events.
	 * @param featureId The panel the menu is in.
	 * @param item The menu item selected.
	 * @return boolean Return true to finish processing of selection, or false to perform the normal menu handling (calling its Runnable or sending a Message to its target Handler).
	 */
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch(item.getItemId()) {
		case ALBUM_CREATE_ID:
			createAlbum();
			return true;
		}		
		return super.onMenuItemSelected(featureId, item);
	}

	/**
	 * We handle album-creation front end stuff here.
	 * Preconditions: 
	 * <ul>
	 * <li>mDbHelper is open</li>
	 * </ul>
	 * Postconditions:
	 * <ul>
	 * <li>A new row in the Albums table exists with a unique title, <em>OR</em></li>
	 * <li>Nothing has changed (in the event of Cancel)</li>
	 * <ul>
	 */
	private void createAlbum() {
		final FrameLayout fl = new FrameLayout(this); 
		final EditText input = new EditText(this);
		input.setLines(1);
		input.setGravity(Gravity.CENTER); 

		fl.addView(input, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.FILL_PARENT));
		
		new AlertDialog.Builder(this)
		.setMessage("New album title:")
		.setView(fl)
		.setPositiveButton("Create", 
			new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					dialog.dismiss();
					
					mDbHelper.addAlbum(input.getText().toString());
					fillData();
				}
			})
		.setCancelable(true)
		.setNegativeButton("Cancel",
			new DialogInterface.OnClickListener() { 
				public void onClick(DialogInterface dialog, int which) { 
					dialog.dismiss(); 
				}
			})
        .create()
		.show();
	}
	
	/**
	 * Handles a return to this activity from the activity we called.
	 * @param requestCode The code of the request we packaged into the Intent that opened the Activity we called.
	 * @param resultCode The code of the result (i.e., OK). We ignore this.
	 * @param intent The initial intent we passed into the activity we called. We ignore this, too.
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
		if (intent!=null) {
			super.onActivityResult(requestCode, resultCode, intent);
			Bundle extras = intent.getExtras();
			
			switch(requestCode) {
			case ACTIVITY_CREATE_ALBUM:
				String title = extras.getString(LensBlasterDB.ALBUM_KEY_TITLE);
				
				mDbHelper.addAlbum(title);
				fillData();
				break;
			case ACTIVITY_ALBUM_VIEW:
				fillData();
				break;
			}
		}
	}
	
	/**
	 * Handles a click to one of the list items.
	 * Postcondition: onActivityResult is called when the calling activity is finished, if one is called.
	 * @param l The ListView object clicked. Ignored.
	 * @param v The view clicked within the ListView. Ignored.
	 * @param position The position within the ListView of the item clicked.
	 * @param id The row ID of the item clicked. Ignored.
	 */
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id){
		super.onListItemClick(l, v, position, id);
		
		if (!mSeparatedList.isEnabled(position)) //clicked on a section header?
			return;
		
		android.util.Log.d("lens","click position = " + position);
		
		Intent i;
		
		switch (position) {
		case ALL_PHOTOS_ALBUM_LIST_ITEM_ID:
			i = new Intent(this, AlbumView.class)
				.putExtra(LensBlasterDB.ALBUM_KEY_ROWID, LensBlasterDB.ALL_PHOTOS_ALBUM_ID)
				.putExtra(LensBlasterDB.ALBUM_KEY_TITLE, "All Photos");
			startActivity(i);
			return;
		case PREFERENCES_LIST_ITEM_ID:
			i = new Intent(this, SettingsView.class);
			startActivity(i);
			return;
		}
		
		
		//This code looks ugly, and it is. The magic 4 there is the number of
		//list items in the separated list adapter that are both enabled (Settings,
		//All Albums) and not enabled (headers) before the first user-defined album.
		//This approach is terrible and doesn't scale for more complicated possible
		//Homescreen views in the future.
		//TODO: run away!
		Cursor c = mAlbumsCursor;
		c.moveToPosition(position - 4);
		
		i = new Intent(this, AlbumView.class)
			.putExtra(
				LensBlasterDB.ALBUM_KEY_ROWID, 
				c.getLong(c.getColumnIndex(LensBlasterDB.ALBUM_KEY_ROWID)))
			.putExtra(
				LensBlasterDB.ALBUM_KEY_TITLE, 
				c.getString(c.getColumnIndex(LensBlasterDB.ALBUM_KEY_TITLE)));

		//We use this call (as opposed to startActivity()) to trigger onActivityResult()
		startActivityForResult(i, ACTIVITY_ALBUM_VIEW);
	}
	
	/**
	 * Called when destroying this activity.
	 * Postcondition:
	 * <ul>
	 * <li>mDbHelper is closed</li>
	 * <ul>
	 */
	@Override
	public void onDestroy(){
		super.onDestroy();
		mDbHelper.close();
	}
}